package com.core.system.service.impl;

import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.system.dao.SystemPermissionMapper;
import com.core.system.dao.SystemTemplateMapper;
import com.core.system.service.ISystemPermissionService;
import com.core.system.service.ISystemTemplateService;
import com.core.system.utils.ConvertUtils;
import com.pojo.dto.SystemPermissionDto;
import com.pojo.dto.SystemTemplateDto;
import com.pojo.entity.SystemPermissionEntity;
import com.pojo.entity.SystemTemplateEntity;
import com.pojo.req.template.InsertTemplateReq;
import com.pojo.req.template.LabelInfo;
import com.pojo.req.template.UpdateTemplateReq;
import com.pojo.resp.template.PermissionOperateResp;
import com.pojo.resp.template.TemplateDetailsResp;
import com.pojo.resp.template.TemplatePageResp;
import com.pojo.resp.template.TemplateParentResp;
import com.utility.constant.Constant;
import com.utility.exception.ServiceException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统菜单表  服务实现类
 * </p>
 *
 * @author hewei
 * @since 2020-11-26
 */
@Service
public class SystemTemplateServiceImpl extends ServiceImpl<SystemTemplateMapper, SystemTemplateEntity> implements ISystemTemplateService {



    @Autowired
    private SystemTemplateMapper systemTemplateMapper;

    @Autowired
    private SystemPermissionMapper systemPermissionMapper;

    @Autowired
    private ISystemPermissionService iSystemPermissionService;

    @Autowired
    private ISystemTemplateService iSystemTemplateService;


    /**
     *  根据菜单对象判断查询集合
     * @param systemTemplateEntity 查询参数对象
     * @return
     */
    public List<SystemTemplateEntity> getTemplateList(SystemTemplateEntity systemTemplateEntity){
        LambdaQueryWrapper<SystemTemplateEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SystemTemplateEntity::getId,
                SystemTemplateEntity::getName,
                SystemTemplateEntity::getLabel,
                SystemTemplateEntity::getParentId,
                SystemTemplateEntity::getSort,
                SystemTemplateEntity::getIcon,
                SystemTemplateEntity::getPath);
        // 未删除
        queryWrapper.eq(SystemTemplateEntity::getIsDelete, Constant.ZERO);
        // 判断对象不为空
        if (!Objects.isNull(systemTemplateEntity)){
            // 判断名称不为空
            if (StringUtils.isNotBlank(systemTemplateEntity.getName())){
                queryWrapper.eq(SystemTemplateEntity::getName, systemTemplateEntity.getName());
            }
            // 判断标签不为空
            if (StringUtils.isNotBlank(systemTemplateEntity.getLabel())){
                queryWrapper.eq(SystemTemplateEntity::getLabel, systemTemplateEntity.getLabel());
            }
            // 判断父级Id不为空
            if (!Objects.isNull(systemTemplateEntity.getParentId())){
                queryWrapper.eq(SystemTemplateEntity::getParentId, systemTemplateEntity.getParentId());
            }
            // 根据创建时间排序
            queryWrapper.orderByDesc(SystemTemplateEntity::getUpdateTime);
            return this.baseMapper.selectList(queryWrapper);

        }
        return this.baseMapper.selectList(queryWrapper);
    }


    /**
     *  根据用户id 查询用户所属街道权限列表
     * @return
     */
    @Override
    public List<TemplatePageResp> getTemplateList(){
        List<SystemTemplateEntity> systemTemplateDtos = getTemplateList(null);
        List<SystemTemplateDto> convert = ConvertUtils.Convert(systemTemplateDtos, new SystemTemplateDto());
        List<SystemTemplateDto> collect = convert.stream().filter(e -> e.getParentId().compareTo(Long.valueOf(Constant.ZERO) ) == 0).collect(Collectors.toList());
        List<TemplatePageResp> systemTemplate = new ArrayList<>();
        collect.forEach(e->{
            recursionFor(e,convert);
            systemTemplate.add(ConvertUtils.Convert(e, TemplatePageResp.class));
        });
        return systemTemplate;
    }


    /**
     *  递归遍历 获取符合条件下级数据
     *
     * @param collect
     * @param systemTemplateDtos
     * @return
     */
    private void recursionFor( SystemTemplateDto collect, List<SystemTemplateDto> systemTemplateDtos){
        List<SystemTemplateDto> proentList = systemTemplateDtos.stream().filter(e -> e.getParentId().equals(collect.getId())).collect(Collectors.toList());
        if (!proentList.isEmpty()){
            collect.setChildren(proentList);
            proentList.forEach(e->{
                this.recursionFor(e,systemTemplateDtos);
            });
        }
    }


    /**
     *  查询顶级菜单列表
     *  可以根据pid 查询下级菜单列表
     * @param pid 父级id
     * @return
     */
    @Override
    public List<TemplateParentResp> getTemplateAllList(String pid) {

        List<SystemTemplateDto> templateDtos = systemTemplateMapper.selectTemplateAllList(pid);
        if (StringUtils.isEmpty(pid)){
            // 顶级菜单
            return ConvertUtils.Convert(templateDtos.stream().filter(e -> e.getParentId().compareTo(Long.valueOf(Constant.ZERO)) == 0).collect(Collectors.toList()),new TemplateParentResp());
        }else {
            List<SystemTemplateDto> dtos = new LinkedList<>();
            /**
             *  判断是否是 操作权限列表
             *      遍历判断 权限操作不为空  封装参数返回
             */
            SystemTemplateEntity systemTemplateEntity = systemTemplateMapper.selectById(pid);
            List<SystemPermissionDto> systemPermissionDtos = systemPermissionMapper.selectLabelPermission(systemTemplateEntity.getLabel(), null);
            if (!systemPermissionDtos.isEmpty()) {
                systemPermissionDtos.forEach(e -> {
                    SystemTemplateDto systemTemplateDto = new SystemTemplateDto();
                    BeanUtils.copyProperties(e, systemTemplateDto);
                    systemTemplateDto.setName(getOperateName(e.getPermissionLabel()));
                    systemTemplateDto.setSort(getOperateSort(e.getPermissionLabel()));
                    dtos.add(systemTemplateDto);
                });
            }
            // 操作权限集合不为空  返回操作权限
            if (!dtos.isEmpty()){
                return ConvertUtils.Convert(dtos,new TemplateParentResp());
            }
        }
        // 最后返回中层菜单集合
        return ConvertUtils.Convert(templateDtos,new TemplateParentResp());
    }

    /**
     * 编辑菜单权限
     * @param insertReq
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTemplate(UpdateTemplateReq insertReq) {
        /**
         *  判断菜单名称是否存在
         */
        LambdaUpdateWrapper<SystemTemplateEntity> templateWrapper = new LambdaUpdateWrapper<>();
        templateWrapper.eq(SystemTemplateEntity::getName,insertReq.getName())
                .eq(SystemTemplateEntity::getIsDelete,Constant.ZERO);
        List<SystemTemplateEntity> temList = systemTemplateMapper.selectList(templateWrapper);
        // 判断菜单名称是否存在 并且 菜单名称不是自己
        if (!temList.isEmpty() && !Objects.equals(temList.get(0).getId(),insertReq.getId())) {
            throw new ServiceException("菜单名称已存在");
        }
        // 编辑菜单
        SystemTemplateEntity templateEntity = new SystemTemplateEntity();
        BeanUtils.copyProperties(insertReq,templateEntity);
        systemTemplateMapper.updateById(templateEntity);
        // 编辑菜单下的权限集合
        List<LabelInfo> permissions = insertReq.getPermission();
        List<SystemPermissionEntity> addPpermissionList = new ArrayList<>();
        List<SystemPermissionEntity> removePpermissionList = new ArrayList<>();
        List<SystemPermissionEntity> permissionList = iSystemPermissionService.getPermissionList(insertReq.getId());
        // 循环编辑筛选 新增的权限
        permissions.forEach(l ->{
            // 使用stream流 判断permissionList 是否包含 code 如果包含则新增
            if (!permissionList.stream().anyMatch(p -> Objects.equals(p.getPermissionLabel(),templateEntity.getLabel()+":" +l.getValue()))) {
                SystemPermissionEntity permission = new SystemPermissionEntity();
                permission.setPermissionLabel(templateEntity.getLabel() + ":" + l.getValue());
                permission.setPermissionName(l.getLabel());
                permission.setTemplateId(insertReq.getId());
                addPpermissionList.add(permission);
            }
        });
        // 循环编辑筛选 移除的权限
        permissionList
                .forEach(l ->{
                    // 使用stream流 判断permissions 是否包含 code 如果包含则删除
                    if (!permissions.stream().anyMatch(p -> Objects.equals(p.getValue(),l.getPermissionLabel().split(":")[1]))) {
                        removePpermissionList.add(l);
                    }
                });

        // 新增权限
        if (!addPpermissionList.isEmpty()) {
            iSystemPermissionService.saveBatch(addPpermissionList);
        }
        // 删除权限
        if (!removePpermissionList.isEmpty()) {
            iSystemPermissionService.removeByIds(removePpermissionList.stream().map(SystemPermissionEntity::getId).collect(Collectors.toList()));
        }
    }

    /**
     *  新增菜单
     * @param insertTemplateReq
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertTemplate(InsertTemplateReq insertTemplateReq) {
        if (Objects.isNull(insertTemplateReq.getParentId())){
            insertTemplateReq.setParentId(Long.valueOf(Constant.ZERO));
        }
        /**
         *  判断菜单名称是否存在
         */
        LambdaUpdateWrapper<SystemTemplateEntity> templateWrapper = new LambdaUpdateWrapper<>();
        templateWrapper.eq(SystemTemplateEntity::getName, insertTemplateReq.getName())
                .eq(SystemTemplateEntity::getIsDelete,Constant.ZERO);
        List<SystemTemplateEntity> systemTemplateEntities = systemTemplateMapper.selectList(templateWrapper);
        if(!systemTemplateEntities.isEmpty()){
            throw new ServiceException("菜单名称已存在");
        }
        // 新增菜单
        SystemTemplateEntity templateEntity = new SystemTemplateEntity();
        BeanUtils.copyProperties(insertTemplateReq,templateEntity);
        systemTemplateMapper.insert(templateEntity);
        // 新增菜单下的权限集合
        List<LabelInfo> permissions = insertTemplateReq.getPermission();
        List<SystemPermissionEntity> permissionList = new ArrayList<>();
        permissions.forEach(l ->{
            SystemPermissionEntity permission = new SystemPermissionEntity();
            permission.setPermissionLabel(templateEntity.getLabel()+":"+l.getValue());
            permission.setPermissionName(l.getLabel());
            permission.setTemplateId(templateEntity.getId());
            permissionList.add(permission);
        });
        iSystemPermissionService.saveBatch(permissionList);
    }


    /**
     *  详情
     * @param id
     * @return
     */
    @Override
    public TemplateDetailsResp details(Long id) {
        // 本机属性
        SystemTemplateDto convert = ConvertUtils.Convert(this.iSystemTemplateService.getById(id), SystemTemplateDto.class);
        // 操作属性
        List<SystemPermissionEntity> permissionList = iSystemPermissionService.getPermissionList(convert.getId());
        // 封装操作集合
        List<PermissionOperateResp> permissionOperateRespList = new ArrayList<>();
        permissionList.forEach(l ->{
            permissionOperateRespList.add(PermissionOperateResp.builder().id(l.getId()).label(l.getPermissionName()).value(l.getPermissionLabel().split(":")[1]).build());

        });
        TemplateDetailsResp templateDetailsResp = ConvertUtils.Convert(convert, TemplateDetailsResp.class);
        templateDetailsResp.setPermission(permissionOperateRespList);
        return templateDetailsResp;
    }

    /**
     *  删除
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        SystemTemplateEntity systemTemplateEntity = new SystemTemplateEntity();
        systemTemplateEntity.setId(id);
        systemTemplateEntity.setIsDelete(Constant.ONE);
        iSystemTemplateService.updateById(systemTemplateEntity);
    }


    /**
     *  判断 返回操作名称
     * @param operate
     * @return
     */
    public static String getOperateName(String operate){
        String[] split = operate.split(":");
        String name = null;
        switch (split[1]){
            case "insert":
                name =  "新增";
                break;
            case "update":
                name =  "编辑";
                break;
            case "delete":
                name =  "删除";
                break;
            case "select":
                name =  "查询";
                break;
            default:
                break;
        }
        return name;
    }

    /**
     *  判断 返回操作名称排序
     * @param operate
     * @return
     */
    public static Short getOperateSort(String operate){
        String[] split = operate.split(":");
        Short sort = null;
        switch (split[1]){
            case "insert":
                sort =  1;
                break;
            case "update":
                sort =  2;
                break;
            case "delete":
                sort =  3;
                break;
            case "select":
                sort =  4;
                break;
            default:
                break;
        }
        return sort;
    }
}
